// appUtils.js
const fs = require('fs');
const path = require('path');
const { WebServer } = require('../server');
const { MessageQueue, TaskQueue } = require('../queue');
const { LabelStudioDB } = require('../dbs/dbApp');
const { DatasetsCloudDB } = require('../dbs/dbDatasesCloud');
const { ModelsCloudDB } = require('../dbs/dbModelsCloud');
const { PipelineDB } = require('../dbs/dbPipeline');
const { PythonEnvManager } = require('./pythonUtils');
const { getUserDataPath } = require('./fileUtils');
const { ModelUtils } = require('./modelUtils');
const { FileWatcherManager } = require('./fileWatcherUtils');
const { AutoUpdater } = require('./autoupdate');
const { VideoProcessor } = require('./videoUtils');
const { ZeroMQBroker } = require('../pipeline/mq/zmq.js');
const { RedisBroker } = require('../pipeline/mq/redis.js');

// 判断是否是远程服务环境
let RemoteListDB;
let RemoteMananger;
try {
    RemoteListDB = require('../dbs/dbRemoteList').RemoteListDB;
    RemoteMananger = require('../remote/remoteManager').RemoteMananger;
} catch (error) {
    console.error('## Can not initialize RemoteMananger!');
}

// 判断是否是electron环境
const ELECTRON_ENV = process.env.ELECTRON_ENV;
if (ELECTRON_ENV) {
    const { dialog } = require('electron');
}

// 初始化app，包括连接数据库，启动本地server
async function initApp(app) {
    // 创建用户数据目录
    if (ELECTRON_ENV) {
        app.userDataPath = app.getPath('userData');
    } else {
        app.userDataPath = getUserDataPath('labelapp');
    }

    // 创建用户数据目录
    const dirs = ['', 'datasets_cloud', 'downloads', 'pipeline'];
    for (const dir of dirs) {
        const dirPath = path.join(app.userDataPath, dir);
        if (!fs.existsSync(dirPath)) {
            fs.mkdirSync(dirPath, { recursive: true });
        }
    }

    // 检查models_cloud是否有更新
    console.log('\n##====================================');
    console.log('## Checking update for App...');
    console.log('##------------------------------------');
    const updater = new AutoUpdater(app);
    await updater.update('models_cloud');
    console.log('##------------------------------------');
    await updater.update('datasets_cloud');
    console.log('##------------------------------------');
    console.log('## Update App OK');
    console.log('##====================================\n');

    // 正式启动服务
    console.log('\n##====================================');
    console.log('## Starting App...');

    // 创建数据库连接
    try {
        if (!app.db) {
            app.db = new LabelStudioDB(app);
        }
        if (!app.datasets_cloud_db) {
            app.datasets_cloud_db = new DatasetsCloudDB(app);
        }
        if (!app.models_cloud_db) {
            app.models_cloud_db = new ModelsCloudDB(app);
        }
        if (!app.pipe_db) {
            app.pipe_db = new PipelineDB(app);
        }
        if (!app.list_dbs) {
            app.list_dbs = {};
        }
    } catch (error) {
        let msg = 'Can not connect to the sqlite database, Error: ' + error.message;
        console.error(msg);
        if (ELECTRON_ENV) {
            dialog.showErrorBox('Database Error: ', msg);
            app.quit();
        }
        return;
    }

    // 启动本地服务
    try {
        if (!app.server) {
            app.server = new WebServer(app, 3000);
            await app.server.start();
        }
    } catch (error) {
        console.error(`Can not initialize Local Web Server, Error: `, error);
        if (ELECTRON_ENV) {
            dialog.showErrorBox('Web Server Error: ', error);
            app.quit();
        }
        return;
    }

    // 启动本地任务队列
    if (!app.queue) {
        app.queue = new MessageQueue();
    }
    if (!app.tasks) {
        app.tasks = new TaskQueue();
        console.log(`## Running Task Queue OK`);
    }

    // 创建文件监控服务
    if (!app.fileWatcher) {
        app.fileWatcher = new FileWatcherManager(app);
        console.log(`## Running File/Directory Monitor OK`);
    }

    // 创建远程管理服务
    if (RemoteListDB && RemoteMananger) {
        try {
            if (!app.remote_db) {
                app.remote_db = new RemoteListDB(app);
            }
            if (!app.remotes) {
                app.remotes = new RemoteMananger(app);
            }
        } catch (error) {
            console.error(`Can not initialize Remote Manager, Error: `, error);
            if (ELECTRON_ENV) {
                dialog.showErrorBox('Remote Manager Error: ', error);
                app.quit();
            }
            return;
        }
    } else {
        console.log(`## Running without RemoteMananger!`);
    }

    // 创建python管理服务
    if (!app.pythonEnv) {
        app.pythonEnv = new PythonEnvManager();
    }

    // 创建模型管理服务
    if (!app.model) {
        app.model = new ModelUtils(app);
    }

    // 创建视频处理服务
    if (!app.video) {
        app.video = new VideoProcessor(app);
    }

    // 初始化本地mq broker，并指定默认的地址
    const brokerType = 'zmq';
    // const brokerType = 'redis';
    if (!app.broker) {
        app.broker = brokerType === 'zmq' ? new ZeroMQBroker() : new RedisBroker();
        await app.broker.start();
    }

    console.log('## Start App OK');
    console.log('##====================================\n');
}

// 关闭app，包括断开数据库，关闭本地server
async function closeApp(app) {
    if (app.server == null && app.db == null && app.list_dbs == null) {
        return;
    }
    if (app.isClosing) {
        return;
    }

    // 设置为正在关闭状态
    app.isClosing = true;
    console.log('\n##====================================');
    console.log('## Closing App...');
    try {
        // 关闭broker
        if (app.broker) {
            app.broker.close();
            app.broker = null;
        }

        // 关闭视频处理服务
        if (app.video) {
            app.video = null;
        }

        // 关闭模型管理服务
        if (app.model) {
            await app.model.clear();
            app.model = null;
        }

        // 关闭python管理服务
        if (app.pythonEnv) {
            app.pythonEnv = null;
        }

        // 关闭远程管理服务
        try {
            if (RemoteMananger) {
                app.remotes && (await app.remotes.close());
                app.remotes = null;
            }
            if (RemoteListDB) {
                app.remote_db && (await app.remote_db.close());
                app.remote_db = null;
            }
        } catch (error) {
            console.error(`Close Remote Manager, Error: `, error);
        }

        // 关闭文件监控服务
        try {
            app.fileWatcher && app.fileWatcher.stopAllWatchers();
            app.fileWatcher = null;
        } catch (error) {
            console.error(`Close FileWatcher, Error: `, error);
        }

        // 关闭本地任务队列
        try {
            app.queue && (await app.queue.clearAll());
            app.queue = null;
            app.tasks && (await app.tasks.clear());
            app.tasks = null;
        } catch (error) {
            console.error(`Close Task Queue, Error: `, error);
        }

        // 关闭本地服务
        try {
            app.server && (await app.server.close());
            app.server = null;
        } catch (error) {
            console.error(`Close Local Web Server, Error: `, error);
        }

        // 关闭数据库连接
        try {
            app.db && (await app.db.close());
            app.db = null;

            app.pipe_db && (await app.pipe_db.close());
            app.pipe_db = null;

            app.datasets_cloud_db && (await app.datasets_cloud_db.close());
            app.datasets_cloud_db = null;

            app.models_cloud_db && (await app.models_cloud_db.close());
            app.models_cloud_db = null;

            for (let id in app.list_dbs) {
                let list_db = app.list_dbs[id];
                list_db && (await list_db.close());
            }
            app.list_dbs = null;
        } catch (error) {
            console.error(`Close Database, Error: `, error);
        }

        // 关闭程序完成
        console.log('## Close App OK!');
        console.log('##====================================\n');
    } catch (err) {
        console.error('Error during app shutdown:', err);
    } finally {
        app.isClosing = false;
    }
}

module.exports = { initApp, closeApp };
